package com.study.zzedu.utils;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v4.content.LocalBroadcastManager;
import android.widget.Toast;

import com.study.zzedu.ui.login.LoginActivity;
import com.study.zzedu.widget.LoadingDialog;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;


/**
 * Created by kiros on 2016/4/11.
 */
public class OkHttpUtils {

    //基本url
    //public static String BASE_URL = "http://192.168.1.205:8080/zzedu/api";
//    public static String URL_FOR_CAS1 = "http://192.168.1.205:8903";
//    public static String URL_FOR_CAS2_ADD = "/zzedu/api/appAccount/checkCas";
    //public static String BASE_URL = "http://192.168.1.205:8903/zzedu/api";

//    public static String URL_FOR_CAS1 = "http://10.102.110.89:10000";
//    public static String URL_FOR_CAS2_ADD = "/zzedu/api/appAccount/checkCas";
    //public static String BASE_URL = "http://10.102.110.89:10000/s/zzedu/api";
    public static String BASE_URL = "http://ols.v.zzu.edu.cn/s";

    public OkHttpClient client;
    //超时时间
    public static final int TIMEOUT = 1000 * 60;

    //json请求
    public static final MediaType JSON = MediaType
            .parse("application/json; charset=utf-8");

    private Handler handler = new Handler(Looper.getMainLooper());

    private static OkHttpUtils httpUtils;
    public static LoadingDialog loadingDialog = null;
    private static Context mContext;
    public  SharedPreferencesHelper sp;
    private LinkedHashMap<String, String> params = new LinkedHashMap<String, String>();

    public OkHttpUtils() {
        this.init();
    }

    public OkHttpUtils(Context context) {
        mContext = context;
        if (loadingDialog == null) {
            loadingDialog = new LoadingDialog(context);
        }
        if (sp == null) {
            sp = new SharedPreferencesHelper(context);
        }
        this.init();
    }
    private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
    private void init() {
        client = new OkHttpClient().newBuilder().cookieJar(new CookieJar() {
            public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
                cookieStore.put(url.host(), cookies);
            }
            public List<Cookie> loadForRequest(HttpUrl url) {
                List<Cookie> cookies = cookieStore.get(url.host());
                return cookies != null ? cookies : new ArrayList<Cookie>();
            }
        }).build();;
    }

    public static OkHttpUtils getInstance(Context context) {
        if (httpUtils == null) {
            synchronized (OkHttpUtils.class) {
                if (httpUtils == null) {
                    httpUtils = new OkHttpUtils(context);
                }
            }
        }
        return httpUtils;
    }
    /**
     * post请求  json数据为body
     */
    public void postJson(String url, String json, final HttpCallBack callBack) {

        RequestBody body = RequestBody.create(JSON, json);
        final Request request = new Request.Builder()
                .header("Content-Type", "application/json")
                .url(url)
                .post(body)
                .build();

        OnStart(callBack);

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(okhttp3.Call cal, IOException e) {
                OnError(callBack, e.getMessage());
                onComplete(callBack);
            }

            @Override
            public void onResponse(okhttp3.Call cal, Response response) throws IOException {
                String data = response.body().string();
                try {
                    //JSONObject jsonObj = new JSONObject(data);
                    if (response.isSuccessful()) {
                        onSuccess(callBack, data);
                    } else {
                        OnError(callBack, response.message());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                onComplete(callBack);
            }
        });
    }
    /**
     * get 请求
     *
     * @param url
     * @param callBack return string
     */
    public void getJsonForString(String url, String[] keys, String[] values, final HttpCallBack callBack) {
        String resUrl;
        params.clear();
        if ((keys != null && values != null)) {
            for (int i = 0; i < keys.length; i++) {
                params.put(keys[i], values[i]);
            }
            resUrl = attachHttpGetParams(url, params);
        } else {
            resUrl = url;
        }
        LogUtil.d("aaaaaa", "请求："+resUrl);
        final Request request = new Request.Builder()
                .header("Content-Type", "application/x-www-form-urlencoded")
                .url(resUrl)
                .build();
        OnStart(callBack);
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(okhttp3.Call cal, IOException e) {
                OnError(callBack, e.getMessage());
                onComplete(callBack);
            }

            @Override
            public void onResponse(okhttp3.Call cal, Response response) throws IOException {
                String data = response.body().string();
                if (response.isSuccessful()) {
                    JSONObject jObject = null;
                    try {
                        jObject = new JSONObject(data);
                        if (401 == jObject.getInt("code")) {
                            mContext.sendBroadcast(new Intent(AppConstant.ACTION_EVENT_401));
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    onSuccess(callBack, data);
                    LogUtil.d("aaaaaa", "返回:"+data);
                } else {
                    OnError(callBack, response.message());
                }
                onComplete(callBack);
            }
        });
    }

    /**
     * @param url   服务器地址
     * @param file  所要上传的文件
     * @return      响应结果
     * @throws IOException
     */
    public ResponseBody upload(String url, String[] keys, String[] values,File file) throws IOException {

        String resUrl;
        params.clear();
        if ((keys != null && values != null)) {
            for (int i = 0; i < keys.length; i++) {
                params.put(keys[i], values[i]);
            }
            resUrl = attachHttpGetParams(url, params);
        } else {
            resUrl = url;
        }

        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getName(),
                        RequestBody.create(MediaType.parse("multipart/form-data"), file))
                .build();
        Request request = new Request.Builder()
                .url(resUrl)
                .post(requestBody)
                .build();
        Response response = client.newCall(request).execute();
        if (!response.isSuccessful())
            throw new IOException("Unexpected code " + response);
        return response.body();
    }

    /**
     * @param url
     * @param keys
     * @param values
     * @param callBack return JSONObject
     */
    public void getJson(String url, String[] keys, String[] values, final HttpCallBack callBack) {
        String resUrl;
        if ((keys != null && values != null)) {
            for (int i = 0; i < keys.length + 1; i++) {
                if (i == keys.length) {
                    params.put("user_id", sp.getStringKey("user_id"));
                } else {
                    params.put(keys[i], values[i]);
                }
            }
            resUrl = attachHttpGetParams(url, params);
        } else {
            resUrl = url;
        }
        LogUtil.d("aaaaaa", resUrl);
        final Request request = new Request.Builder()
                .header("Content-Type", "application/json")
                .addHeader("token", sp.getStringKey("token"))
//                .addHeader("user_id", sp.getStringKey("user_id"))
                .url(resUrl)
                .build();

        OnStart(callBack);
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(okhttp3.Call cal, IOException e) {
                LogUtil.d("aaaaaa", e.getMessage());
                OnError(callBack, e.getMessage());
                onComplete(callBack);
            }

            @Override
            public void onResponse(okhttp3.Call cal, Response response) throws IOException {
                String data = response.body().string();
                LogUtil.d("aaaaaa", data);
                onComplete(callBack);
                try {
                    JSONObject jsonObj = new JSONObject(data);
                    if (response.isSuccessful()) {
                        if (jsonObj.optBoolean("success")) {
                            onSuccess(callBack, jsonObj);
                        } else {
                            Looper.prepare();
                            Toast.makeText(mContext, jsonObj.optString("message"), Toast.LENGTH_LONG).show();
                            if (jsonObj.optString("code").equals("10001")) {
                                mContext.startActivity(new Intent(mContext, LoginActivity.class));
                            }
                            Looper.loop();
                        }
                    } else {
                        OnError(callBack, response.message());
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    Looper.prepare();
                    Toast.makeText(mContext, "服务器异常", Toast.LENGTH_LONG).show();
                    Looper.loop();
                    LogUtil.d("aaaaaa", e.toString());
                }
            }
        });
    }
    /**
     * 为HttpGet 的 url 方便的添加多个name value 参数。
     *
     * @param url
     * @param params
     * @return
     */
    public static String attachHttpGetParams(String url, LinkedHashMap<String, String> params) {

        Iterator<String> keys = params.keySet().iterator();
        Iterator<String> values = params.values().iterator();
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("?");

        for (int i = 0; i < params.size(); i++) {
            String value = null;
            try {
                value = URLEncoder.encode(values.next(), "utf-8");
            } catch (Exception e) {
                e.printStackTrace();
            }

            stringBuffer.append(keys.next() + "=" + value);
            if (i != params.size() - 1) {
                stringBuffer.append("&");
            }
        }
        //LogUtil.d("aaaaaa", "stringBuffer===>" + url + stringBuffer.toString());
        return url + stringBuffer.toString();
    }

    public void OnStart(HttpCallBack callBack) {
        if (!NetWorkUtils.isNetworkConnected(mContext)) {
            //Toast.makeText(mContext, "网络跑火星上了...", Toast.LENGTH_SHORT).show();
            loadingDialog.dismiss();
        } else {
            if (callBack != null) {
                LogUtil.d("aaaaaaa", loadingDialog.isShowing() + "");
                if (!loadingDialog.isShowing()) {
                    callBack.onStart(true);
                }
            }
        }
    }
    public void onComplete(HttpCallBack callBack) {
        if (callBack != null) {
            callBack.onComplete();
        }
    }
    /**
     * @param callBack
     * @param data
     */
    public void onSuccess(final HttpCallBack callBack, final String data) {
        if (callBack != null) {
            handler.post(new Runnable() {
                @Override
                public void run() {//在主线程操作
                    try {
                        callBack.onSuccess(data);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    /**
     * @param callBack
     * @param obj
     */
    public void onSuccess(final HttpCallBack callBack, final JSONObject obj) {
        LogUtil.d("aaaaaa", obj.toString());
        if (callBack != null) {
            handler.post(new Runnable() {
                @Override
                public void run() {//在主线程操作
                    callBack.onSuccess(obj);
                }
            });
        }
    }

    public void OnError(final HttpCallBack callBack, final String msg) {
        LogUtil.e("aaaaaa", msg);
        if (callBack != null) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    callBack.onError(msg);
                }
            });
        }
    }
    public static abstract class HttpCallBack {
        //开始
        public void onStart(Boolean isLoadingDialog) {
            if (loadingDialog != null) {
                if (isLoadingDialog) {
                    loadingDialog.show();
                } else {
                    loadingDialog.dismiss();
                }
            }
        }

        //成功回调返回String
        public void onSuccess(String data) throws JSONException {
            int jj = 90;
        }
        //成功回调
        public abstract void onSuccess(JSONObject obj);
        //失败
        public abstract void onError(String msg);

        //结束
        public void onComplete() {
            if (loadingDialog != null) {
                loadingDialog.dismiss();
            }
        }
    }
}

